/**==============================================================================
            Copyright (c) 2013 Moritz Hader, Marcel Schrder
            All Rights Reserved.

	@file  Heimdall3DObject.java

	@brief  The Heimdall3DObject-class represents aka. capsulates the properties 
	of an arbitrary object in the 3D-environment. It inherits position, rotation 
	and scale properties from HeimdallAbstractElement and contains a mesh as well 
	as a surface.

  This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
==============================================================================*/
package de.ibm.dhbw.heimdall.engine;

import de.ibm.dhbw.heimdall.HeimdallAR;
import de.ibm.dhbw.heimdall.engine.math.HVector3D;

/**
 * @author moritzhader
 *
 */
public class Heimdall3DObject extends HeimdallAbstractElement{
	private HeimdallMesh mesh;
	private HeimdallSurface surface;
	
	private int identifier;
	private int markerID;
	
	//Native
	//Load the native library into the code
	static{
		HeimdallAR.LoadNativeLib("HeimdallARNative");
	}

	native void CopyTransformNative(int id, int type);
	native void Copy3DObjectToNative();
	native void Detach3DObjectFromNative(int id);
	
	public Heimdall3DObject() {
		this.setLocPosition(new HVector3D(0.0f, 0.0f, 0.0f));
		this.setLocRotation(new HVector3D(0.0f, 0.0f, 0.0f));
		this.setLocScale(new HVector3D(1.0f, 1.0f, 1.0f));
		
		this.IPosition = new HVector3D(0.0f, 0.0f, 0.0f);
		this.IRotation =  new HVector3D(0.0f, 0.0f, 0.0f);
		this.IScale =  new HVector3D(1.0f, 1.0f, 1.0f);
		
		this.setInfoID(-1);
	}
	
	public Heimdall3DObject(HeimdallMesh hm, HeimdallSurface hs) {

		this.setLocPosition(new HVector3D(0.0f, 0.0f, 0.0f));
		this.setLocRotation(new HVector3D(0.0f, 0.0f, 0.0f));
		this.setLocScale(new HVector3D(1.0f, 1.0f, 1.0f));
		
		this.IPosition = new HVector3D(0.0f, 0.0f, 0.0f);
		this.IRotation =  new HVector3D(0.0f, 0.0f, 0.0f);
		this.IScale =  new HVector3D(1.0f, 1.0f, 1.0f);
		

		this.setInfoID(-1);
		
		this.setMesh(hm);
		this.setSurface(hs);
	}
	
	public void attachMesh(HeimdallMesh hm){
		this.setMesh(hm);
	}
	
	public void attachSurface(HeimdallSurface hs){
		this.setSurface(hs);
	}
	
	

	public void setIdentifier(int i){
		this.identifier = i;
	}
	
	public int getIdentifier(){
		return  identifier;
	}
	
	public HeimdallMesh getMesh(){
		return this.mesh;
	}
	
	public HeimdallSurface getSurface(){
		return this.surface;
	}
	
	public float[] getAdjustedPositionFloat(){
		
		//The adjusted Value equals the local value added to the inherited value
		return this.getLocPosition().add(this.IPosition).getFloat();
	}
	
	public float[] getAdjustedRotationFloat(){
		
		//The adjusted Value equals the local value added to the inherited value
		return this.getLocRotation().add(this.IRotation).getFloat();
	}
	
	public float[] getAdjustedScaleFloat(){
		
		//The adjusted Value equals the local value multiplied to the inherited value
		return this.getLocScale().scale(this.IScale).getFloat();
	}
	
	@Override
	public void setLocPosition(HVector3D locPosition) {
		super.setLocPosition(locPosition);
		
		if(this.identifier != -1){
			CopyTransformNative(this.identifier,1);
		}
	}
	
	@Override
	public void setLocScale(HVector3D locScale) {
		super.setLocScale(locScale);
		
		if(this.identifier != -1){
			CopyTransformNative(this.identifier,2);
		}
	}
	
	@Override
	public void setLocRotation(HVector3D locRotation){
		super.setLocRotation(locRotation);
		
		if(this.identifier != -1){
			CopyTransformNative(this.identifier,3);
		}
	}
	
	/**
	 * Overwritten super-method that makes an element inherit its fathers transformations.
	 * After a 3D-Object inherits, it must propagate its new transformations down native-code.
	 */
	@Override
	public void inheritProperties(HeimdallAbstractElement elem){
		super.inheritProperties(elem);
		
		if(this.identifier != -1){
			CopyTransformNative(this.identifier,1);
			CopyTransformNative(this.identifier,2);
			CopyTransformNative(this.identifier,3);
		}
	}
	
	/**
	 * Tell this Object to call the native-method that copies the Object-values
	 * down to the native code.
	 */
	@Override
	public void natifyObject(){
		Copy3DObjectToNative();
	}
	
	/**
	 * Tell this Object to detach himself from the native-environment
	 */
	@Override
	public void denatifyObject(){
		Detach3DObjectFromNative(this.identifier);
	}
	public int getMarkerID() {
		return markerID;
	}
	public void setMarkerID(int markerID) {
		this.markerID = markerID;
	}
	public void setMesh(HeimdallMesh mesh) {
		this.mesh = mesh;
	}
	public void setSurface(HeimdallSurface surface) {
		this.surface = surface;
	}
}
